using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Common;
using Common.NotifyEvent;
using SExperiment.ExperimentResult;
using SProject;
using SProject.BasicInformation;

namespace SExperiment
{
	[Serializable]
	public class Well : NotifyPropertyChanged
	{
		private int _ID;

		private int _RowIndex;

		private int _ColumnIndex;

		private bool _ModelA;

		private bool _IsInValid;

		private string _CellName;

		private Sample _Sample;

		private int _MultiTubeID;

		[NonSerialized]
		private WellResult _Result;

		public int ID
		{
			get
			{
				return _ID;
			}
			set
			{
				if (_ID != value)
				{
					_ID = value;
					OnPropertyChanged("ID");
				}
			}
		}

		public int RowIndex
		{
			get
			{
				return _RowIndex;
			}
			set
			{
				if (_RowIndex != value)
				{
					_RowIndex = value;
					OnPropertyChanged("RowIndex");
				}
			}
		}

		public int ColumnIndex
		{
			get
			{
				return _ColumnIndex;
			}
			set
			{
				if (_ColumnIndex != value)
				{
					_ColumnIndex = value;
					OnPropertyChanged("ColumnIndex");
				}
			}
		}

		public bool ModelA
		{
			get
			{
				return _ModelA;
			}
			set
			{
				if (_ModelA != value)
				{
					_ModelA = value;
					OnPropertyChanged("ModelA");
				}
			}
		}

		public bool IsInValid
		{
			get
			{
				return _IsInValid;
			}
			set
			{
				if (_IsInValid != value)
				{
					if (Sample == null)
					{
						value = false;
					}
					_IsInValid = value;
					OnPropertyChanged("IsInValid");
				}
			}
		}

		public string CellName
		{
			get
			{
				if (string.IsNullOrEmpty(_CellName))
				{
					return ((char)(_RowIndex + 65)).ToString() + (_ColumnIndex + 1);
				}
				return _CellName;
			}
			set
			{
				if (!(_CellName == value))
				{
					_CellName = value;
					OnPropertyChanged("CellName");
				}
			}
		}

		public Project Project
		{
			get
			{
				if (_Sample != null)
				{
					return _Sample.Project;
				}
				return null;
			}
		}

		public Sample Sample
		{
			get
			{
				return _Sample;
			}
			private set
			{
				if (_Sample != value)
				{
					Sample sample = _Sample;
					_Sample = value;
					if (value == null)
					{
						MultiTubeID = 0;
						Result = null;
						IsInValid = false;
					}
					else
					{
						Result = ResultFactory.CreateWellResult(value.Project.BasicInfo.Type);
					}
					OnPropertyChanged("Sample", _Sample, sample);
					OnPropertyChanged("Project");
				}
			}
		}

		public List<SampleTargetItem> Targets
		{
			get
			{
				if (_Sample == null)
				{
					return new List<SampleTargetItem>();
				}
				return _Sample.Items.Where((SampleTargetItem s) => s.TubeNo == _MultiTubeID).ToList();
			}
		}

		public int MultiTubeID
		{
			get
			{
				return _MultiTubeID;
			}
			private set
			{
				_MultiTubeID = value;
				OnPropertyChanged("MultiTubeID");
				OnPropertyChanged("Targets");
			}
		}

		public string TubeName
		{
			get
			{
				if (Project != null)
				{
					return (from s in Project.Target.Items
						where s.TubeNo == MultiTubeID
						select s.TubeName).FirstOrDefault();
				}
				return null;
			}
		}

		public WellResult Result
		{
			get
			{
				if (_Result == null)
				{
					_Result = new WellResult();
				}
				return _Result;
			}
			set
			{
				if (_Result != value)
				{
					_Result = value;
					OnPropertyChanged("Result");
				}
			}
		}

		public void DeleteSmaple()
		{
			SetSample(null, 0);
		}

		public void SetSample(Sample sample, int tubeID)
		{
			_MultiTubeID = tubeID;
			Sample = sample;
			MultiTubeID = MultiTubeID;
		}

		public void ResetResult()
		{
			if (Project != null)
			{
				Result = ResultFactory.CreateWellResult(Project.BasicInfo.Type);
			}
		}

		public void SaveToStream(StreamEx stream)
		{
			stream.Write(PropertyKey.Key_Well);
			List<PropertyKey> list = new List<PropertyKey>();
			List<byte[]> list2 = new List<byte[]>();
			list.Add(PropertyKey.Key_IsInValid);
			list2.Add(BytesConverter.GetBytes(IsInValid));
			list.Add(PropertyKey.Key_MultiTubeID);
			list2.Add(BytesConverter.GetBytes(MultiTubeID));
			list.Add(PropertyKey.Key_CellName);
			list2.Add(BytesConverter.GetBytes(CellName));
			list.Add(PropertyKey.Key_SampleResult);
			StreamEx streamEx = new StreamEx();
			Result.SaveToStream(streamEx);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			stream.Write(PropertyKey.Key_Index);
			stream.WriteIndex(list, list2);
			stream.Flush();
		}

		public bool ReadFromStream(StreamEx stream)
		{
			PropertyKey propertyKey = stream.ReadKey();
			if (propertyKey == PropertyKey.Key_Well)
			{
				propertyKey = stream.ReadKey();
				if (propertyKey == PropertyKey.Key_Index)
				{
					List<PropertyKey> keys;
					List<byte[]> dates;
					stream.ReadIndex(out keys, out dates);
					for (int i = 0; i < keys.Count; i++)
					{
						switch (keys[i])
						{
						case PropertyKey.Key_IsInValid:
							IsInValid = BytesConverter.BytesToBool(dates[i]);
							break;
						case PropertyKey.Key_MultiTubeID:
							MultiTubeID = BytesConverter.BytesToInt(dates[i]);
							break;
						case PropertyKey.Key_CellName:
							CellName = BytesConverter.BytesToString(dates[i]);
							break;
						case PropertyKey.Key_SampleResult:
						{
							StreamEx streamEx = new StreamEx();
							streamEx.Write(dates[i]);
							streamEx.Seek(0L, SeekOrigin.Begin);
							Result.ReadFromStream(streamEx);
							streamEx.Close();
							break;
						}
						}
					}
					return true;
				}
				stream.Seek(-4L, SeekOrigin.Current);
				while (true)
				{
					switch (stream.ReadKey())
					{
					case PropertyKey.Key_IsInValid:
						IsInValid = stream.ReadBool();
						break;
					case PropertyKey.Key_MultiTubeID:
						MultiTubeID = stream.ReadInt();
						break;
					case PropertyKey.Key_CellName:
						CellName = stream.ReadString();
						break;
					case PropertyKey.Key_DisplayText:
						stream.ReadString();
						break;
					default:
						stream.Seek(-4L, SeekOrigin.Current);
						return true;
					}
				}
			}
			stream.Seek(-4L, SeekOrigin.Current);
			return false;
		}
	}
}
